package com.abysscore.yachtdesign;

import java.awt.Color;
import java.awt.List;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.Array;
import java.util.ArrayList;
import org.apache.commons.lang.ArrayUtils;

import com.abysscore.yachtdesign.delphi.DelphiTools;

public class TFreeFileBuffer {
	private long FCapacity;              // Amount of bytes allocated
	private int FCount;              // The amount of bytes actually used
	private int FPosition;              // current position when reading information from the buffer
	private TFreeFileVersion FVersion;
	private byte[] FData;
	private final int FileBufferBlockSize = 4096;
	
	private void FGrow(int size)
	{
		int AmountToGrow;

		AmountToGrow=1024;

		if (size>AmountToGrow)
			AmountToGrow=size;
	
		FCapacity = FCapacity+AmountToGrow;
	}
	
	public byte[] resizeArray(byte array[], long newSize)
	{
		byte newArray[] = new byte[(int) newSize];
		for(int i = 0 ; i < newSize ; i++)
		{
			newArray[i] = array[i];
		}
		return (newArray);
	} // END OF METHOD
	
	private void FSetCapacity(long dataLeft)
	{
		FCapacity = dataLeft;
		
		int I;

		FData = resizeArray(FData,dataLeft);
		
		for (I=(int) (FCapacity+1); I < dataLeft; I++)
			FData[I-1] = (byte) 255;
		FCapacity=dataLeft;
	}


	public void Add(String Text)
	{
		;
	}
	public void Add(boolean booleanValue)
	{
		;
	}
	public void Add(double FloatValue)
	{
		
	}
	public void Add(int intValue)
	{
		int Size=-1;

		Size = DelphiTools.SizeOf(intValue);
		if (FCount+Size>FCapacity)
			FGrow(Size);
		DelphiTools.Move(intValue,FData[FCount],Size);
		FCount = FCount+Size;
	}
	public void Add(TFreeFileVersion Version)
	{
		
	}
	public void Add(T3DCoordinate Coordinate)
	{
		
	}
	public void Add(T3DPlane Plane)
	{
		
	}
	public void Add(Object source, int Size)
	{
		
	}
	public void Add(TJPegImage JPegImage)
	{
		;
	}
	public void Load(String Output)
	{
		int I=0;
		int Size=0;
		char Ch;

		Load(Size);
		Output = "";
		if (FPosition+Size<=FCount)
		{
			for (I=1; I <= Size; I++)
			{
				Ch=(char)FData[FPosition];
				FPosition++;
				Output+=Ch;
			}
		}
		else 
			System.err.println("public void Load(String Output)");
			//MessageDlg(UserString(192)+'!',mtError,[mbOk],0);
	}
	public void Load(int Output)
	{
		int Size;
		
		Size=DelphiTools.SizeOf(Output);
		Output=0;
		if (FPosition+Size<=FCount)
		{
			DelphiTools.Move(FData[FPosition],Output,Size);
			FPosition += Size;
		}
		else 
			System.err.println("public void Load(int Output)");
			//MessageDlg(UserString(192)+'!',mtError,[mbOk],0);
	}
	public void Load(TFreeFileVersion Output)
	{
		;
	}
	public void Load(boolean Output)
	{
		int Size;

		Size=DelphiTools.SizeOf(Output);
		Output=false;
		if ((FPosition+Size)<=FCount)
		{
			DelphiTools.Move(FData[FPosition],Output,Size);
			FPosition+=Size;
		}
		else 
			System.err.println("public void Load(boolean Output)");
			//MessageDlg(UserString(192)+'!',mtError,[mbOk],0);
	}
	public void Load(double Output)
	{
		int Size;
		
		Size=DelphiTools.SizeOf(Output);
		Output=0.0;
		if ((FPosition+Size)<=FCount)
		{
			DelphiTools.Move(FData[FPosition],Output,Size);
			FPosition+=Size;
		}
		else 
			System.err.println("public void Load(double Output)");
			//MessageDlg(UserString(192)+'!',mtError,[mbOk],0);
	}
	public void Load(Color Output)
	{
		int Size;
		
		Size=DelphiTools.SizeOf(Output);
		Output=Color.BLACK;
		if ((FPosition+Size)<=FCount)
		{
			DelphiTools.Move(FData[FPosition],Output,Size);
			FPosition+=Size;
		}
		else 
			System.err.println("public void Load(Color Output)");
			//MessageDlg(UserString(192)+'!',mtError,[mbOk],0);
	}
	public void Load(T3DCoordinate Output)
	{
		int Size;
		
		Size=DelphiTools.SizeOf(Output);
		Output=null;
		
		if ((FPosition+Size)<=FCount)
		{
			DelphiTools.Move(FData[FPosition],Output,Size);
			FPosition += Size;
		}
		else 
			System.err.println("public void Load(T3DCoordinate Output)");
			//MessageDlg(UserString(192)+'!',mtError,[mbOk],0);
	}
	public void Load(T3DPlane Output)
	{
		;
	}
	public void Load(TJPegImage JPegImage)
	{
		//var Stream:TMemoryStream;
		int W=0;
		int H=0;
		int Size=0;
	
		Load(W);
		Load(H);
		Load(Size);
		//Stream=TMemoryStream.Create;
		//Stream.SetSize(Size);
		//Stream.Write(FData[FPosition],Size);
		FPosition+=Size;
		//Stream.Position:=0;
		//JPegImage.LoadFromStream(Stream);
		//Stream.Destroy;
	}
	public void Load(Object Dest, int Size)
	{
		;
	}

	public void Clear()
	{
		;
	}
	public void LoadFromFile(String Filename) throws IOException
	{
		File FFile;
		long DataLeft;
		int Tmp;
		long Size;
		
		FFile = new File(Filename);
		FileInputStream fstr = new FileInputStream(FFile);
		
		//system.Reset(FFile,1);
		FCount=0;
		DataLeft=FFile.length();
		Capacity(DataLeft);
		byte[] tmpData = null;
		FPosition=0;
		if (DataLeft<0)
			return;
		while(DataLeft>0)
		{
			if (DataLeft<FileBufferBlockSize)
				Size = DataLeft;
		    else 
		    	Size=FileBufferBlockSize;
			Tmp=fstr.read(tmpData, FCount, FileBufferBlockSize);
		    
		    DataLeft = DataLeft-Tmp;
		    FData = ArrayUtils.addAll(FData, tmpData);
		    
		    FCount = FCount +Tmp;
		}
		fstr.close();
	}
	public void Reset()
	{
		;                             // reset the data before reading
	}
	public void SaveToFile(String Filename)
	{
		;
	}
	public long Capacity() { return FCapacity; }
	public void Capacity(long dataLeft) { FSetCapacity(dataLeft); }
	public int Count() { return FCount; }
	public TFreeFileVersion Version() { return FVersion; }
	public void Version(TFreeFileVersion val) { FVersion=val; }

public TFreeFileBuffer()
{
	FData = null;
}

	public TFreeFileBuffer(File arg0, String arg1) {
		//super(arg0, arg1);
		// TODO Auto-generated constructor stub
	}
/*
	

	void TFreeFileBuffer.Add(Version:TFreeFileVersion);
	var Size:int;
	begin
	   FVersion=Version;
	   Size=SizeOf(Version);
	   if Count+Size>Capacity then FGrow(Size);
	   Move(Version,FData[FCount],Size);
	   Inc(FCount,Size);
	end;{TFreeFileBuffer.Add}

	void TFreeFileBuffer.Add(Coordinate:T3DCoordinate);
	var Size:int;
	begin
	   Size=SizeOf(Coordinate);
	   if Count+Size>Capacity then FGrow(Size);
	   Move(Coordinate,FData[FCount],Size);
	   Inc(FCount,Size);
	end;{TFreeFileBuffer.Add}

	void TFreeFileBuffer.Add(Plane:T3DPlane);
	var Size:int;
	begin
	   Size=SizeOf(Plane);
	   if Count+Size>Capacity then FGrow(Size);
	   Move(Plane,FData[FCount],Size);
	   Inc(FCount,Size);
	end;{TFreeFileBuffer.Add}

	void TFreeFileBuffer.Add(const source;Size:int);
	var S: PChar;
	    I: int;
	begin
	   S=PChar(@Source);
	   if Count+Size>Capacity then FGrow(Size);
	   for I = 0 to size-1 do
	   begin
	      FData[FCount]=Byte(S[I]);
	      Inc(FCount);
	   end;
	end;{TFreeFileBuffer.Add}

	void TFreeFileBuffer.Add(JPegImage:TJPEGImage);
	var Stream:TMemoryStream;
	    Size:int;
	begin
	   Add(JPEGImage.Width);
	   Add(JPEGImage.Height);
	   Stream=TMemoryStream.Create;
	   JPEGImage.SaveToStream(Stream);
	   Size=Stream.Size;
	   Stream.Position=0;
	   Add(Size);
	   if Count+Size+20>Capacity then FGrow(Size+20);
	   Stream.Read(FData[FCount],Size);
	   inc(FCount,Size);
	   Stream.Destroy;
	end;{TFreeFileBuffer.Add}

	void TFreeFileBuffer.Load(var JPegImage:TJPEGImage);
	var Stream:TMemoryStream;
	    W,H,Size:int;
	begin
	   Load(W);
	   Load(H);
	   Load(Size);
	   Stream=TMemoryStream.Create;
	   Stream.SetSize(Size);
	   Stream.Write(FData[FPosition],Size);
	   Inc(FPosition,Size);
	   Stream.Position=0;
	   JPEGImage.LoadFromStream(Stream);
	   Stream.Destroy;
	end;{TFreeFileBuffer.Add}

	void TFreeFileBuffer.Load(var Dest;Size:int);
	var D : PChar;
	    I : int;
	begin
	   D = PChar(@Dest);
	   for I=0 to size-1 do
	   begin
	      D[I]=Char(FData[FPosition]);
	      Inc(FPosition);
	   end;
	end;{TFreeFileBuffer.Load}

	void TFreeFileBuffer.Load(var Output:String);
	var I,Size : int;
	    Ch     : Char;
	begin
	   Load(Size);
	   Output='';
	   if FPosition+Size<=FCount then
	   begin
	      for I=1 to Size do
	      begin
	         Ch=Char(FData[FPosition]);
	         Inc(FPosition);
	         Output=Output+Ch;
	      end;
	   end else MessageDlg(UserString(192)+'!',mtError,[mbOk],0);
	end;{TFreeFileBuffer.Load}

	void TFreeFileBuffer.Load(var Output:int);
	var Size : int;
	begin
	   Size=4;
	   Output=0;
	   if FPosition+Size<=FCount then
	   begin
	      Move(FData[FPosition],Output,Size);
	      Inc(FPosition,Size);
	   end else MessageDlg(UserString(192)+'!',mtError,[mbOk],0);
	end;{TFreeFileBuffer.Load}

	void TFreeFileBuffer.Load(var Output:TFreeFileVersion);
	var Size : int;
	begin
	   Size=SizeOf(Output);
	   if FPosition+Size<=FCount then
	   begin
	      Move(FData[FPosition],Output,Size);
	      Inc(FPosition,Size);
	   end else MessageDlg(UserString(192)+'!',mtError,[mbOk],0);
	end;{TFreeFileBuffer.Load}

	void TFreeFileBuffer.Load(var Output:T3DPlane);
	var Size : int;
	begin
	   Size=SizeOf(Output);
	   if FPosition+Size<=FCount then
	   begin
	      Move(FData[FPosition],Output,Size);
	      Inc(FPosition,Size);
	   end else MessageDlg(UserString(192)+'!',mtError,[mbOk],0);
	end;{TFreeFileBuffer.Load}

	void TFreeFileBuffer.Add(Text:String);
	var Size:int;
	begin
	   Size=Length(Text);
	   Add(Size);
	   if Count+Size>Capacity then FGrow(Size);
	   Move(Text[1],FData[FCount],Size);
	   Inc(FCount,Size);
	end;{TFreeFileBuffer.Add}

	void TFreeFileBuffer.Add(booleanValue:boolean);
	var Size:int;
	begin
	   Size=1;//SizeOf(booleanValue);
	   if Count+Size>Capacity then FGrow(Size);
	   Move(booleanValue,FData[FCount],Size);
	   Inc(FCount,Size);
	end;{TFreeFileBuffer.Add}

	void TFreeFileBuffer.Add(FloatValue:double);
	var Size:int;
	begin
	   Size=SizeOf(FloatValue);
	   if Count+Size>Capacity then FGrow(Size);
	   Move(FloatValue,FData[FCount],Size);
	   Inc(FCount,Size);
	end;{TFreeFileBuffer.Add}

	constructor TFreeFileBuffer.Create;
	begin
	   Inherited Create;
	   Clear;
	end;{TFreeFileBuffer.Create}

	void TFreeFileBuffer.Clear;
	begin
	   FCapacity=0;
	   FCount=0;
	   FPosition=0;
	   Setlength(FData,0);
	end;{TFreeFileBuffer.Clear}

	destructor TFreeFileBuffer.Destroy;
	begin
	    Clear;
	    Inherited Destroy;
	end;{TFreeFileBuffer.Destroy}

	// reset the data before reading
	void TFreeFileBuffer.Reset;
	begin
	   FPosition=0;
	end;{TFreeFileBuffer.Reset}

	void TFreeFileBuffer.SaveToFile(Filename:string);
	var FFile      : File;
	    DataWritten: int;
	    DataLeft   : int;
	    Tmp        : int;
	    Size       : int;
	begin
	   AssignFile(FFile,Filename);
	   Rewrite(FFile,1);
	   DataWritten=0;
	   DataLeft=Count;
	   while DataWritten<Count do
	   begin
	      if DataLeft<FileBufferBlockSize then Size=DataLeft
	                                      else Size=FileBufferBlockSize;
	      BlockWrite(FFile,FData[DataWritten],Size,Tmp);
	      Dec(DataLeft,Tmp);
	      Inc(DataWritten,Tmp);
	   end;
	   Closefile(FFile);
	end;{TFreeFileBuffer.SaveToFile}
	*/
}
